#pragma once
#include<iostream>
#include<memory>
#include<sys/epoll.h>
#include"Socket.hpp"
#include"Connection.hpp"
#include"IOServer.hpp"
#include"EpollServer.hpp"
#include"Protocol.hpp"
//专门获取新连接的模块（链接管理器）
class Listener : public Connection{
    public:
        Listener(int port)
            : _listen_sockfd(new TcpSocket(_port))
            , _port(port)
        {
            _listen_sockfd->Build_Socket(_port);
            SetFd(_listen_sockfd->Fd());
            SetEvents(EPOLLIN|EPOLLET);
        }
        int Get_Sock_fd()
        {
            return _listen_sockfd->Fd();
        }
        virtual void _read_callback() override//读事件回调
        {
            //一次来的可能有多个链接,一次性全部读完（因为是ET模式）
            while(true){
                int acerrno = 0;//获取accept出错的原因
                struct sockaddr_in client_addr;
                int new_sockfd = _listen_sockfd->Accept((struct sockaddr*)&client_addr,&acerrno);
                if(new_sockfd >= 0){
                    
                    //将获得的新链接加入到epoll中
                    auto conn = std::make_shared<IOServer>(new_sockfd);//根据fd创建IOServer对象(且为非阻塞)
                    conn->SetHandleMessage(HandleMessage);//设置处理报文的回调函数(包含在Protocol.hpp中)
                    
                    //将IOServer对象加入到epoll中(这里是用listen所指的服务器对象，不能用conn的epoll_owner，因为conn里还没有初始化epoll_owner)
                    GetEpollOwner()->Add_Connection(conn);

                    // LOG(log_level::DEBUG)<<"add new connection "<<new_sockfd;

                }else{//出错,查看errno
                    if(acerrno == EAGAIN || acerrno == EWOULDBLOCK){//表示阻塞,已经没有可读事件,退出循环
                        LOG(log_level::DEBUG)<<"accept all connection";
                        break;
                    }else if(acerrno == EINTR){//信号中断,继续
                        LOG(log_level::DEBUG)<<"accept interrupt by signal";
                        continue;
                    }else{//正真出错,退出循环
                        LOG(log_level::WARNING)<<"accept error ";
                        break;
                    }
                }
            }
        }
        virtual void _write_callback() override//写事件回调
        {
            //无
        }
        virtual void _except_callback() override//异常事件回调
        {
            //无
        }
        ~Listener()
        {
            _listen_sockfd->Close();
        }
    private:
        int _port;
        std::unique_ptr<Socket> _listen_sockfd;
};